"""
基本数据类型,
"""

import copy
# 字符串，数字，布尔，列表，字典，序列，元祖
# 可变数据类型：列表，字典，集合
# 不可变数据类型：数字（整数和浮点数，复数），字符串，元组
##定义全局变量
#  python命名规则： __
int_one = 1  # 定义一个整数
float_one = 22.1  # 定义一个浮点数
complex_demo = complex(2, 4)  # 定义一个复数，或complex = 2.4j(必须定义虚数部分)
# print(int_one)
str_one = 'hello,world'
str_str = 'hellolleh'  # 定义一个回文字符串

list_one = ['张三', '李四', '王五', 12, 32]
list_two = ['张三', '李四', '王五']
dict_one = {'name':'张三','age':18,'sex':'男',}
table_one = ('张三', '李四', )  # 元组是个无序数列，每次运行元组的位置都是变化的，
# print(table_one)

# 布尔类型
bool_one = True  # 定义一个布尔类型变量
bool_two = False
# print(bool_one, type(bool_one))
# print(bool_two, type(bool_two))


def str_demo():
    # 字符串操作方法
    # 1，通过索引进行截取slice[start:end:step]  step默认为1
    print(str_one[0])  # 通过下标获取字符串的单个字符
    print(str_one[1:3])
    print(str_one[1:3:2])  # 通过切片获取字符串的部分字符
    # 2,字符串拼接，通过+号进行拼接
    str_two = 'hello'
    str_three = 'world'
    print(str_two + str_three)
    print(str_one.join(str_two))  # join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串
    # 3，字符串重复
    print(str_two * 3)
    # 4,字符串长度，和最值
    print(len(str_two))  # len()方法返回字符串的长度
    print(max(str_two))  # max()方法返回字符串中最大的字符
    print(min(str_two))  # min()方法返回字符串中最小的字符
    # 5,字符串转换
    print(str(123))
    print(int('123'))
    print(float('123.1'))
    print(complex(1, 2))
    # 6,格式化字符串
    print('我叫%s,今年%d岁' % ('张三', 18))
    # 7,字符串查找和计数
    print('该字符串出现的位置为', str_two.index('l'))  # index()方法返回字符串中第一次出现的指定值的索引
    print(str_two.find('l'))
    print(str_two.count('l'))
    # 8,字符串替换
    print(str_two.replace('l', 'L'))
    # 9,字符串分割
    print(str_two.split('l'))  # split([delimiter[, maxsplit]])  delimiter:分隔符，
    # 默认为所有的空字符，包括空格、换行(\n)、制表符(\t)等,默认全部分割
    # 10,字符串大小写转换
    print(str_two.upper())  # 转换为大写
    str_four = 'HELLO'
    print(str_four.lower())  # 转换为小写
    # 11, 字符串格式化
    # %s 格式化字符串
    print('我叫%s,今年%d岁' % ('张三', 18))
    print('我叫{},今年{}岁'.format('张三', 18))


def list_demo():
    # 列表操作方法
    # 1,列表索引
    global list_one  # 声明全局变量
    print(list_one[0])
    print(list_one[1:3])
    print(list_one[1:3:2])
    print(list_one[-1])
    print(list_one[-1:-3:-1])  # 通过负数索引获取列表的元素,负数索引从-1开始
    print(list_one[::-1])  # 通过负数索引获取列表的元素,负数索引从-1开始

    # 2,列表添加元素
    list_one.append('赵六')
    print(list_one)
    list_one.insert(1, '老七')
    print(list_one)
    list_one.extend(['王七', '李四'])
    print(list_one)
    # 3，列表删除元素
    list_one.remove('张三')  # 根据值删除元素
    print('当前列表为：', list_one)
    list_one.pop(-4)  # 根据索引删除元素
    list_one.pop(-4)  # 根据索引删除元素
    print(list_one)
    # 4,列表排序
    list_one.sort()  # sort(Key=None,reverse=False)  reverse:是否反转，默认为False
    print(list_one)
    sorted(list_one)  # 注意：sorted()函数与sort使用方法不一样，一个是变量名.，一个是在括号里
    print(list_one)
    list_one.reverse()  # 列表反转
    print(list_one)
    # sort() 列表原地排序，默认从小到大
    # sorted() 返回一个新的列表，默认从小到大
    # reverse() 列表反转
    # 5,列表拷贝
    list_two = list_one.copy()  # 浅拷贝，深拷贝需要导入copy库，使用copy.deepcopy(list_one)，生成一个新的列表
    print(list_two)
    # 6,列表清空
    list_two.clear()
    print(list_two)
    # 7,列表计数
    print(list_one.count('张三'))


def dict_demo():
    # 字典操作方法
    # 1,创建字典
    global dict_one # 全局声明

    # dict_one = {'name': '张三', 'age': 18}  # 通过{}创建字典
    list_one = [["a", 1], ["b", 2], ["c", 3]]  # 通过dict()函数创建字典，或者说通过dict函数将二维数组转换为字典
    dict_two = dict(list_one)
    print(dict_two)
    dict_three = dict(name='李四', age=25, sex='女')
    print(dict_three)
    # 2, 字典元素的读取
    print(dict_one['name'])  # 通过字典键的下标方式读取字典值，子典的下标是字典的“键”，而列表和元组访问时下标必须为整数值。使用下标的方式访问字典“值”时，若指定的键不存在则抛出异常
    print(dict_one.get('name'))  # 通过get方法获取指定键对应的值，键若不存在可返回None
    print(dict_one.get('name', '未找到改字段'))  # 通过get方法获取指定键对应的值，键若不存在返回指定值
    # 通过keys()方法返回键
    print(dict_one.keys())  # 输出字典的键，输出字典的键 dict_keys(['name', 'age', 'sex'])
    print(type(dict_one.keys()))
    # 通过values()返回值
    print(dict_one.values())
    # 字典遍历，通过items方法返回键值对
    print(dict_one.items())
    for key, value in dict_one.items():
        print(key, value)
    for i in dict_one:
        print(i)  # 如果直接对字典遍历，只能返回字典键
    # 3,字典添加或更新修改元素
    dict_one['sex'] = '男'  # 如果键值对不存在，则新增，如果键值对存在则对值进行修改
    print(dict_one)
    print(dict_one.update(dict_two))  # 通过update()方法将另一个字典全部添加到当前字典中，如果两个字典中存在相同的“键”，则以另一个字典中的“值”为准，对当前字典进行更新
    # 4, 字典删除
    del dict_one['name']  # 通过del命令删除字典中指定“键”对应的元素
    del dict_three  # 通过del命令删除整个字典
    print('当前删除值后的字典为:', dict_one)
    dict_one.clear()  # 通过clear()方法删除字典中所有元素,返回一个空字典
    print(dict_one)
    dict_two.pop('a')  # 通过pop()方法根据键删除字典元素
    print(dict_two)
    dict_two.popitem()  # 通过popitem()方法随机删除字典中的一个键值对
    print(dict_two)
    # 5, 判断键是否在字典中
    print('字典判断')
    print('b' in dict_two)
    # 6,排序
    print(sorted(dict_two))  # 根据键对字典进行排序
    print(sorted(dict_two, key=dict_two.__getitem__))  # 根据“值Value”进行排序,__getitem__魔术方法返回键对应的值
    # 根据items()进行排序
    print(dict_two.items())
    # 等同于
    print(sorted(dict_two.items(), key=lambda d: d[0]))
    # 7, 字典的浅拷贝
    dictionary = {"卷心菜":'cabbage', "午餐":['carrot','nooning']}
    dictionary2 = dictionary.copy()
    print('浅拷贝后：',dictionary,dictionary2)
    print(dictionary)
    print(dictionary2)
    dictionary2['午餐'].remove('nooning')
    print('浅拷贝删除后：',dictionary,dictionary2)
    print(dictionary)
    print(dictionary2)
    dictionary = {"卷心菜": 'cabbage', "午餐": ['carrot', 'nooning']}
    dictionary3 = copy.deepcopy(dictionary)
    print('深拷贝后：',dictionary,dictionary3)
    print(dictionary)
    print(dictionary3)
    dictionary3['午餐'].remove('nooning')
    print('深拷贝删除后：',dictionary,dictionary3)
    print(dictionary)
    print(dictionary3)

def tuple_demo():
    # 元组(元组是不可变数据类型,不可以进行更改)
    # 访问元组中的值
    table_two = ('北京', '上海', '深圳', '江苏')
    print(table_two[0])  # 通过下标获取元组的单个值,顺序访问,下标从0开始
    print(table_two[-1])  # 通过下标获取元组的单个值
    print(table_two[0:1])  # 通过切片获取元组的部分值
    print(table_two[-1:0])  # 通过切片获取元组的部分值
    # 查找元组下标
    print(table_two.index('北京'))  # 通过index()方法获取元组下标
    print(table_two.count('北京'))  # count()方法统计元素在元组中出现的次数
    # 元组合并
    print(table_one + table_two)
    # 元组遍历
    for i in table_two:
        print(i)
    # 元组解包:把批量的数据进行批量的赋值
    a1, b1, c1 = (1, 2, 3)
    print('元组解包:', a1, b1, c1)



def set_demo():
    # 集合(集合会自动去重,列表若要去重可先转变为集合再转换为列表)
    set_one = {1, 2, 3, 4, 5}
    set_two = {'张三', 1, 2}
    # 枚举:返回对应的元素和索引值
    for i, v in enumerate(set_one):
        print('index: %s,value: %s' % (i, v))
    # 集合的增加和删除
    set_one.add(1)  # 增加一个元素
    set_one.update([5, 2, 3, 6])  # 添加多个元素，并自动去重
    set_one.pop()  # 删除最前面的元素【第一个】
    set_one.remove(2)  # 指定删除某个元素,如果元素不存在会报错
    set_one.discard(2)  # 指定删除某个元素,如果元素不存在不会报错d
    set_one.clear() # 清空集合
    # 集合的运算,
    ## len(),max(),min(),sorted()等方法同样适合于集合
    # 通过intersection()和&实现集合交集运算
    print('交集:', set_one.intersection(set_two))
    print('交集:', set_one & set_two)
    # 通过union和|实现集合并集运算
    print('并集', set_one.union(set_two))
    print('并集', set_one | set_two)
    # 通过difference()方法实现集合差集运算
    print('差集', set_one.difference(set_two))  # s1 - (s1&s2)
    print('差集', set_two.difference(set_one))  # s2 - (s1&s2)
    # s4是s3的超集【包含s3的全部】  ###当两个集合相同时，互为超集
    s3 = {1, 2}
    s4 = {1, 2, 3}
    print(s3.issuperset(s4))  # 超集
    print(s3.issubset(s4))  # 子集
    print(s3.isdisjoint(s4))  # 两个集合不相交返回True


def main():
    # str_demo()
    # list_demo()
    # dict_demo()
    tuple_demo()
    # set_demo()


if __name__ == "__main__":
    main()
